/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.util;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.AccessController;
import java.util.List;

import org.zhiqim.kernel.annotation.AnAlias;

/**
 * 系统相关工具类
 *
 * @version v1.0.0 @author zouzhigang 2014-2-27 新建与整理
 * 
 * 键相关值的描述 
 * java.vendor                      Java 运行时环境供应商 
 * java.vendor.url                  Java 供应商的 URL 
 * java.home                        Java 安装目录 
 * java.vm.specification.version    Java 虚拟机规范版本 
 * java.vm.specification.vendor     Java 虚拟机规范供应商 
 * java.vm.specification.name       Java 虚拟机规范名称 
 * java.vm.vendor                   Java 虚拟机实现供应商 
 * java.specification.version       Java 运行时环境规范版本 
 * java.specification.vendor        Java 运行时环境规范供应商 
 * java.specification.name          Java 运行时环境规范名称 
 * java.class.version               Java 类格式版本号 
 * java.io.tmpdir                   默认的临时文件路径 
 * java.compiler                    要使用的 JIT 编译器的名称 
 * java.ext.dirs                    一个或多个扩展目录的路径 
 * 
 * @see AccessController.doPrivileged   可能需要访问前申请特权。
 */
@AnAlias("Systems")
public class Systems
{
    /*******************************************************************/
    //常用的判断和获取方法
    /*******************************************************************/
    
    /** 判断是否是Windows */
    public static boolean isWindows()
    {
        return Strings.startsWithIgnoreCase(getOsName(), "windows");  
    }
    
    /** 判断是否是MacOS */
    public static boolean isMacOS()
    {//Mac OS X || Darwin
        String osName = getOsName();
        return Strings.startsWithIgnoreCase(osName, "mac") || Strings.startsWithIgnoreCase(osName, "darwin");  
    }
    
    /** 判断是否是Linux */
    public static boolean isLinux()
    {
        return Strings.startsWithIgnoreCase(getOsName(), "linux");  
    }
    
    /** 获取工程进程ID */
    public static int getPid()
    {
        RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();  
        String name = runtime.getName(); //得到的格式: "pid@hostname"  
        return Ints.toInt(name.substring(0, name.indexOf('@')), -1);  
    }
    
    /** JAVA版本号是否1.7以上(含1.7) */
    public static boolean isJavaVersionMoreThen7()
    {
        return getJavaVersion().compareTo("1.7") >= 0;
    }
    
    /** JAVA版本号是否1.8以上(含1.8) */
    public static boolean isJavaVersionMoreThen8()
    {
        return getJavaVersion().compareTo("1.8") >= 0;
    }

    /** 等同于getPathSeparator */
    public static String getClassPathSeparator()
    {
        return getPathSeparator();
    }
    
    /** 增加库路径  */
    public static void addLibraryPath(String dir)
    {
        String libraryPath = System.getProperty("java.library.path");
        System.setProperty("java.library.path", dir+getClassPathSeparator()+libraryPath);
    }
    
    /** 获取类路径信息通过分隔符成数组 */
    public static String[] getClassPaths()
    {
        return Arrays.toStringArray(getClassPath(), getClassPathSeparator());
    }
    
    /** 获取类路径信息通过分隔符成列表 */
    public static List<String> getClassPathList()
    {
        return Lists.toStringList(getClassPath(), getClassPathSeparator());
    }
    
    public static void setClassPath(String classPath)
    {
        System.setProperty("java.class.path", classPath);
    }
    
    /*******************************************************************/
    //属性设置获取等基本操作方法
    /*******************************************************************/
    
    /** 设置属性 */
    public static void setProperty(String key, String value)
    {
        System.setProperty(key, value);
    }
    
    /** 获取属性 */
    public static String getProperty(String key)
    {
        return System.getProperty(key);
    }
    
    /** 获取环境变量 */
    public static String getEnv(String key)
    {
        return System.getenv(key);
    }
    
    /** 获取属性或环境变量，优先属性 */
    public static String getPropOrEnv(String key)
    {
        String value = System.getProperty(key);
        return (value == null)?System.getenv(key):value;
    }
    
    /** 替换属性 */
    public static String replaceProperty(String str)
    {
        if (Validates.isEmpty(str))
            return str;
        
        while(true)
        {
            int sInd = str.indexOf("${");
            if (sInd == -1)
                break;
            
            int eInd = str.indexOf("}", sInd+2);
            if (eInd == -1 || eInd <= sInd+2)
                break;
            
            String env = str.substring(sInd+2, eInd);
            String value = getProperty(env);
            str = Replaces.replaceAllEscape(str, "${"+env+"}", value);
        }

        return str;
    }
    
    /** 替换路径属性 */
    public static String replacePropertyPath(String str)
    {
        return (Validates.isEmpty(str))?str:Replaces.replaceAllEscape(replaceProperty(str), "\\", "/");
    }
    
    /*******************************************************************/
    //属性常用的获取方法
    /*******************************************************************/
    
    /** 获取操作系统名称 */
    public static String getOsName()
    {
        return System.getProperty("os.name");
    }
    
    /** 获取操作系统的架构 */
    public static String getOsArch()
    {
        return System.getProperty("os.arch");
    }
    
    /** 获取操作系统的架构 */
    public static String getOsVersion()
    {
        return System.getProperty("os.version");
    }
    
    /** 获取用户账号名称 */
    public static String getUserName()
    {
        return System.getProperty("user.name");
    }
    
    /** 获取用户主目录 */
    public static String getUserHome()
    {
        return System.getProperty("user.home");
    }    
    
    /** 获取用户当前工作目录(工程根目录) */
    public static String getUserDir()
    {
        return System.getProperty("user.dir");
    }
    
    /** 取得系统的文件分隔符，在window系统返回"\"，在unix/linux系统返回"/" */
    public static String getFileSeparator()
    {
        return System.getProperty("file.separator");
    }
    
    /** 取得系统的路径分隔符，在window系统返回";"，在unix/linux系统返回":"） */
    public static String getPathSeparator()
    {
        return System.getProperty("path.separator");
    }
    
    /** 取得系统的行分隔符，在window系统返回"\r\n"，在unix/linux系统返回"\n" */
    public static String getLineSeparator()
    {
        return System.getProperty("line.separator");
    }
    
    /** 获取JAVA版本号，返回如1.4,1.5 */
    public static String getJavaVersion()
    {
        return System.getProperty("java.version");
    }
    
    /** 获取全类路径信息 */
    public static String getClassPath()
    {
        return System.getProperty("java.class.path");
    }
    
    /** 获取加载库时搜索的库路径列表  */
    public static String getLibraryPath()
    {
        return System.getProperty("java.library.path");
    }
    
    /** 获取虚拟机信息 */
    public static String getVmInfo()
    {
        return System.getProperty("java.vm.info");
    }
    
    /** 获取虚拟机名称 */
    public static String getVmName()
    {
        return System.getProperty("java.vm.name");
    }
    
    /** 获取虚拟机版本 */
    public static String getVmVersion()
    {
        return System.getProperty("java.vm.version");
    }
    
    /** 获取系统工程文件编码 */
    public static String getFileEncoding()
    {
        return System.getProperty("file.encoding");
    }
    
    /** 获取系统编码 */
    public static String getSystemEncoding()
    {
        return System.getProperty("sun.jnu.encoding");
    }
    
    /** 获取主机名 */
    public static String getHosthame()
    {
        try
        {
            InetAddress localMachine = InetAddress.getLocalHost();
            return localMachine.getCanonicalHostName();
        }
        catch (UnknownHostException e)
        {
            return "localhost";
        }
    }
}
